home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Tools / dbmedit / dbmedit.c next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  8.1 KB  |  437 lines

  1. /* dbmedit: edit a dbm file */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Tools/dbmedit/RCS/dbmedit.c,v 6.0 1991/12/18 20:29:41 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Tools/dbmedit/RCS/dbmedit.c,v 6.0 1991/12/18 20:29:41 jpo Rel $
  9.  *
  10.  * $Log: dbmedit.c,v $
  11.  * Revision 6.0  1991/12/18  20:29:41  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "head.h"
  19. #include "util.h" 
  20. #include "dbase.h"
  21. #include "sys.file.h"
  22. #include <ctype.h>
  23.  
  24. extern char *ppdbm;
  25. extern char *dupfpath();
  26. extern char *multcat();
  27.  
  28. #ifdef GDBM
  29. GDBM_FILE    thedb;
  30. #define store(x,y)    gdbm_store (thedb, x, y, GDBM_REPLACE)
  31. #define fetch(x)    gdbm_fetch (thedb, x)
  32. #else
  33. #ifndef GCC_DBM_OK
  34. #if sparc && defined(__GNUC__)    /* work around bug in gcc 1.37 sparc version */
  35.  #error GCC and dbm do not get along on a sparc - compile with cc.
  36. #endif
  37. #endif
  38. #endif
  39.  
  40. # ifdef NDBM
  41. # define        fetch(x)        dbm_fetch(thedb, (x))
  42. # define        store(x, y)     dbm_store(thedb, (x), (y), DBM_REPLACE)
  43. # define        delete(x)       dbm_delete(thedb, (x))
  44. DBM     *thedb;
  45. # endif
  46.  
  47.  
  48. datum   dcons();
  49.  
  50. char    ibuf[LINESIZE];
  51. #define MARGS   100
  52. char    *cargv[MARGS];                /* max number of args on a line */
  53. int     cargc;
  54.  
  55. int     help(), add(), del(), change(), print(), quit();
  56.  
  57. struct  cmds    {
  58.     char    *cm_name;
  59.     int     (*cm_func)();
  60.     char    *cm_help;
  61. } cmds[] = {
  62.     "help", help,   "Print out help text",
  63.     "add",  add,    "Add an entry",
  64.     "delete", del,  "Delete an entry",
  65.     "change", change, "Change an entry",
  66.     "print", print, "Print an entry",
  67.     "quit", quit,   "Quit the program",
  68.     "h",    help,   0,              /* single character aliases */
  69.     "a",    add,    0,
  70.     "d",    del,    0,
  71.     "c",    change, 0,
  72.     "p",    print,  0,
  73.     "q",    quit,   0,
  74.     "?",    help,   0,
  75. }, *curcmd;
  76.  
  77. int     verbose;
  78.  
  79. /*
  80.  * dbm expanded structure
  81.  */
  82.  
  83. #define MDB     50
  84.  
  85. int     ndbents;
  86.  
  87. struct  db      {
  88.     char    *d_table;
  89.     char    *d_value;
  90. } dbs[MDB], *lastdb;
  91.  
  92. main(argc, argv)
  93. int argc;
  94. char **argv;
  95. {
  96.     int opt;
  97.     extern int optind;
  98.     extern char *optarg;
  99.  
  100.     sys_init(argv[0]);
  101.  
  102.     while ((opt = getopt (argc, argv, "vd:")) != EOF) {
  103.         switch (opt) {
  104.             case 'v':
  105.             verbose++;
  106.             break;
  107.             case 'd':
  108.             ppdbm = optarg;
  109.             break;
  110.             default:
  111.             fprintf(stderr, "dbmedit: unknown argument '%c'\n",
  112.                 opt);
  113.             exit(NOTOK);
  114.         }
  115.     }
  116.     argv += optind;
  117.     argc -= optind;
  118.     if(!isstr(ppdbm)) {
  119.         fprintf(stderr, "dbmedit: cannot find database path\n");
  120.         exit(NOTOK);
  121.     }
  122.     dbfinit(ppdbm);
  123.  
  124.     /* if got command line arguments process these instead */
  125.     if(argc > 0){
  126.         avfix(argc, argv);
  127.         if(findcmd() < 0)
  128.             exit(1);
  129.         exit((*curcmd->cm_func)());
  130.     }
  131.  
  132.     for(;;){
  133.         printf("dbmedit> ");
  134.         (void) fflush(stdout);
  135.         if (gets(ibuf) == NULL)
  136.             exit(0);
  137.         if (!isstr(ibuf))
  138.             continue;
  139.         if ((cargc = sstr2arg(ibuf, MARGS, cargv, " \t")) == 0)
  140.             continue;
  141.         if(findcmd() < 0)
  142.             continue;
  143.         (*curcmd->cm_func)();
  144.     }
  145. }
  146.  
  147. avfix(ac, av)
  148. int ac;
  149. register char   **av;
  150. {
  151.     register char   **ap;
  152.  
  153.     for(ap = cargv; ac ; ac--, cargc++)
  154.         *ap++ = *av++;
  155. }
  156.  
  157. findcmd()
  158. {
  159.     register struct cmds *cp;
  160.  
  161.     for(cp = cmds ; cp < &cmds[sizeof(cmds)/sizeof(cmds[0])] ; cp++)
  162.         if(lexequ(cp->cm_name, cargv[0]) == 0){
  163.             curcmd = cp;
  164.             return(0);
  165.         }
  166.     fprintf(stderr, "dbmedit: unknown command '%s'\n", cargv[0]);
  167.     return(-1);
  168. }
  169.  
  170. help()
  171. {
  172.     register struct cmds *cp;
  173.  
  174.     for(cp = cmds ; cp < &cmds[sizeof(cmds)/sizeof(cmds[0])] ; cp++)
  175.         if(cp->cm_help != 0)
  176.             printf("%s\t\t%s\n", cp->cm_name, cp->cm_help);
  177. }
  178.  
  179. datum
  180. dcons(value)
  181. char    *value;
  182. {
  183.     datum d;
  184.  
  185.     d.dptr = value;
  186.     d.dsize = strlen(value)+1;
  187.     return(d);
  188. }
  189.  
  190. datum
  191. dconskey(value)
  192. char    *value;
  193. {
  194.     char    *p;
  195.  
  196.     for (p = value; *p; p++)
  197.         if (isupper(*p))
  198.             *p = tolower(*p);
  199.     return(dcons(value));
  200. }
  201.  
  202. dssplit(str)
  203. register char   *str;
  204. {
  205.     register struct db      *dp;
  206.     static  char    ti[512];
  207.  
  208.     ndbents = 0;
  209.     str = strcpy(ti, str);
  210.     for(dp = dbs ; dp < &dbs[sizeof(dbs)/sizeof(dbs[0])]; dp++){
  211.         if(*str == 0)
  212.             break;
  213.         dp->d_table = str;
  214.         while(*str && *str != ' ')
  215.             str++;
  216.         *str++ = 0;
  217.         dp->d_value = str;
  218.         while(*str && *str != FS)
  219.             str++;
  220.         ndbents++;
  221.         if(*str == FS)
  222.             *str++ = 0;
  223.     }
  224.     lastdb = dbs + ndbents;
  225. }
  226.  
  227. add()
  228. {
  229.     datum   d;
  230.     register struct db      *dp;
  231.  
  232.     if(cargc != 4){
  233.         fprintf(stderr, "Usage: add key table value\n");
  234.         return(9);
  235.     }
  236.     d = fetch(dconskey(cargv[1]));
  237.     if(d.dptr == 0){
  238.         if (verbose)
  239.             printf("Creating new key \"%s\" value \"%s %s\"\n",
  240.                         cargv[1], cargv[2], cargv[3]);
  241.         dp = lastdb = dbs;
  242.         goto newalias;
  243.     }
  244.     dssplit(d.dptr);
  245.     for(dp = dbs ; dp < lastdb ; dp++){
  246.         if(lexequ(dp->d_table, cargv[2]) == 0){
  247.             fprintf(stderr,
  248.               "key \"%s\" already has a value in table \"%s\"\n",
  249.                             cargv[1], cargv[2]);
  250.             return(99);
  251.         }
  252.     }
  253. newalias:;
  254.     lastdb++;
  255.     dp->d_table = cargv[2];
  256.     dp->d_value = cargv[3];
  257.     return(dscons());
  258. }
  259.  
  260. del()
  261. {
  262.     int     i;
  263.     datum   d;
  264.     register struct db      *dp;
  265.     int     changed = 0;
  266.  
  267.     if (cargc <= 2) {
  268.         fprintf(stderr, "Usage: delete key table|* [table ...]\n");
  269.         return(9);
  270.     }
  271.  
  272.     d = fetch(dconskey(cargv[1]));
  273.     if (d.dptr == 0) {
  274.         fprintf(stderr, "key \"%s\" not found in database\n", cargv[1]);
  275.         return(99);
  276.     }
  277.     if (strcmp(cargv[2], "*") == 0) {        /* all entries */
  278.         if (verbose)
  279.             printf("Deleteing key \"%s\"\n", cargv[1]);
  280.         goto delall;
  281.     }
  282.     dssplit(d.dptr);
  283.     for(i = 2 ; i < cargc ; i++) {
  284.         for(dp = dbs ; dp < lastdb ; dp++) {
  285.             if(dp->d_table && lexequ(dp->d_table, cargv[i]) == 0) {
  286.                 if (verbose)
  287.                     printf("deleting \"%s\" from table \"%s\"\n",
  288.                             cargv[1], cargv[i]);
  289.                 changed++;
  290.                 dp->d_table = 0;
  291.                 break;
  292.             }
  293.         }
  294.         if(dp >= lastdb){
  295.             fprintf(stderr,
  296.                 "\"%s\" does not have a value in table \"%s\"\n",
  297.                             cargv[1], cargv[i]);
  298.             continue;
  299.         }
  300.     }
  301.     if(!changed)
  302.         return(99);
  303.     if(lastdb - changed <= dbs) {
  304.         if (verbose)
  305.             printf("All values deleted for \"%s\" - deleting key\n",
  306.                                 cargv[1]);
  307. delall:;
  308.         if(delete(dcons(cargv[1])) < 0)
  309.             fprintf(stderr, "Delete failed\n");
  310.         return(0);
  311.     }
  312.     return(dscons());
  313. }
  314.  
  315. change()
  316. {
  317.     datum   d;
  318.     register struct db      *dp;
  319.  
  320.     if(cargc < 3 || cargc > 4) {
  321.         fprintf(stderr, "Usage: change key table [value]\n");
  322.         return(9);
  323.     }
  324.  
  325.     d = fetch(dconskey(cargv[1]));
  326.     if(d.dptr == 0) {
  327.         if (verbose)
  328.             fprintf(stderr, "key \"%s\" not found in database\n",
  329.                 cargv[1]);
  330.         if (cargc == 4)
  331.             return(add());
  332.         return(0);
  333.     }
  334.     dssplit(d.dptr);
  335.     for(dp = dbs ; dp < lastdb ; dp++)
  336.         if(lexequ(dp->d_table, cargv[2]) == 0){
  337.             if (cargc == 3)
  338.                 return(del());
  339.             if (verbose)
  340.                 printf("changing \"%s\" to \"%s\"\n",
  341.                         dp->d_value, cargv[3]);
  342.             dp->d_value = cargv[3];
  343.             break;
  344.         }
  345.  
  346.     if(dp >= lastdb){
  347.         if (cargc == 4)
  348.             return(add());
  349.         return(0);
  350.     }
  351.     return(dscons());
  352. }
  353.  
  354. print()
  355. {
  356.     datum   d;
  357.     register struct db      *dp;
  358.  
  359.     if(cargc < 2){
  360.         fprintf(stderr, "Usage: print key [table]\n");
  361.         return(9);
  362.     }
  363.  
  364.     d = fetch(dconskey(cargv[1]));
  365.     if(d.dptr == 0){
  366.         fprintf(stderr, "key \"%s\" not found in database\n", cargv[1]);
  367.         return(99);
  368.     }
  369.     dssplit(d.dptr);
  370.     for(dp = dbs ; dp < lastdb ; dp++)
  371.         if (cargc == 2 || lexequ(dp->d_table, cargv[2]) == 0 ||
  372.             lexequ("*", cargv[2]) == 0)
  373.             printf("key \"%s\": table \"%s\": value \"%s\"\n",
  374.                 cargv[1], dp->d_table, dp->d_value);
  375.     return(0);
  376. }
  377.  
  378. dscons()
  379. {
  380.     char    tbuf[ENTRYSIZE];
  381.     datum   d;
  382.     register struct db      *dp;
  383.     register char   *p, *q;
  384.     int     changed = 0;
  385.  
  386.     for(p = tbuf, dp = dbs ; dp <lastdb ; dp++){
  387.         if((q = dp->d_table) == 0)
  388.             continue;
  389.         if(p != tbuf)
  390.             *(p-1) = FS;
  391.         changed++;
  392.         while(*p++ = *q++);
  393.         *(p-1) = ' ';
  394.         for(q = dp->d_value ; *p++ = *q++;);
  395.     }
  396.     if (!changed) {
  397.         fprintf(stderr, "dbmedit: internal error 'no change'\n");
  398.         return(99);
  399.     }
  400.     d = dcons (tbuf);
  401.  
  402.     if (store(dconskey(cargv[1]), d) < 0) {
  403.         fprintf(stderr, "dbmedit: cannot store new value for '%s'\n", cargv[1]);
  404.     }
  405.     return(0);
  406. }
  407.  
  408. /*
  409.  * Initialize the dbm file.
  410.  */
  411.  
  412. dbfinit(filename)
  413. char *filename;
  414. {
  415. #ifdef GDBM
  416.     char name[BUFSIZ];
  417.     (void) sprintf (name, "%s.gdbm", filename);
  418.     filename = name;
  419.     if ((thedb = gdbm_open (filename, 0, GDBM_WRITER, 0666, NULL)) == NULL) {
  420. #else
  421. # ifdef NDBM
  422.     if((thedb = dbm_open(filename, O_RDWR, 0666)) == NULL) {
  423. # else
  424.     if(dbminit(filename) < 0) {
  425. # endif
  426. #endif
  427.         fprintf (stderr, "could not initialize data base '%s'", filename);
  428.         perror("");
  429.         exit(99);
  430.     }
  431. }
  432.  
  433. quit()
  434. {
  435.     exit(0);
  436. }
  437.